﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.IO;

namespace BattleShipLibrary
{
    public class BattleField
    {
        public ArrayList AllShipLocations = new ArrayList();
        Cell emptyCell;
        Cell[,] field = new Cell[10, 10];
        bool Enemy = false;

        public bool _Enemy
        {
            get { return Enemy; }
            set { Enemy = value; }
        }
        public Cell[,] Field
        {
            get { return field; }
            set { field = value; }
        }
        public BattleField()
        {
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    emptyCell = new Cell('F', j);
                    field[i, j] = emptyCell;
                }
            }
        }
        //отрисовка поля
        public void Output()
        {

            for(int i = 0; i<=10; i++)
            {
                for (int j = 0; j <=10; j++)
                {
                    //нумерация столбцов
                    if (i == 0)
                    {
                        Console.BackgroundColor = ConsoleColor.Black;
                        if (j == 0)
                        {
                            Console.Write("  "); //для выравнивания
                        }
                        else
                        {
                            int letter = 'A'+j-1;
                            Console.Write(Convert.ToChar(letter));
                        }
                    }
                    else
                    {
                        //нумерация строк
                        if (j == 0)
                        {
                            Console.BackgroundColor = ConsoleColor.Black;
                            if (i < 10)
                            {
                                
                                Console.Write(" " + i); //для выравнивания
                            }
                            else
                            {
                                
                                Console.Write(i);
                            }
                            
                        }
                        else
                        {
                            field[i - 1, j - 1].Output(Enemy);
                        }
                        
                    }
                    
                }
                Console.WriteLine();
            }
        }
        public void Output2()
        {
            for (int i = 0; i <= 10; i++)
            {
                Console.SetCursorPosition(20, i);
                for (int j = 0; j <= 10; j++)
                {
                    
                    //нумерация столбцов
                    if (i == 0)
                    {
                        Console.BackgroundColor = ConsoleColor.Black;
                        if (j == 0)
                        {
                            Console.Write("  "); //для выравнивания
                        }
                        else
                        {
                            int letter = 'A' + j - 1;
                            Console.Write(Convert.ToChar(letter));
                        }
                    }
                    else
                    {
                        //нумерация строк
                        if (j == 0)
                        {
                            Console.BackgroundColor = ConsoleColor.Black;
                            if (i < 10)
                            {

                                Console.Write(" " + i); //для выравнивания
                            }
                            else
                            {

                                Console.Write(i);
                            }

                        }
                        else
                        {
                            field[i - 1, j - 1].Output(Enemy);
                        }

                    }

                }
                Console.WriteLine();
            }
        }

        public Cell[,] addShip(Ship ship, BattleField f)
        {


            Utils a = new Utils();
            int Y1ShipCoordinate = ship.ShipLocattion()[0,1];
            int X1ShipCoordinate = ship.ShipLocattion()[0,0];
            int Y2ShipCoordinate = ship.ShipLocattion()[ship.ShipLocattion().Length/ship.ShipLocattion().Rank-1,1];
            int X2ShipCoordinate = ship.ShipLocattion()[ship.ShipLocattion().Length/ship.ShipLocattion().Rank-1,0];
            int[,] shipNeighborhood = a.GetNeighborhood(X1ShipCoordinate, Y1ShipCoordinate, X2ShipCoordinate, Y2ShipCoordinate);

            //Проверяем, не перескается ли добавляемый корабль с уже расставленными на поле
           
            //File.Delete("C:\\Temp\\BSG.txt");
            //File.CreateText("C:\\Temp\\BSG.txt");

            using (StreamWriter str = new StreamWriter("C:\\Temp\\BSG.txt"))
            {
                foreach (int[,] ShL in f.AllShipLocations)
                {
                    //Console.WriteLine("-----------------");
                    for (int i = 0; i < ShL.Length / ShL.Rank; i++)
                    {
                        //Console.WriteLine(i+"я ShL = "+Convert.ToChar(ShL[i,0]+'A')+Convert.ToInt32(ShL[i,1]+1));
                        for (int j = 0; j < shipNeighborhood.Length / shipNeighborhood.Rank; j++)
                        {
                            //Console.WriteLine(j + "я shipNeighborhood = " + Convert.ToChar(shipNeighborhood[j, 0] + 'A') + Convert.ToInt32(shipNeighborhood[j, 1] + 1));
                            for (int k = 0; k < (ship.ShipLocattion().Length / ship.ShipLocattion().Rank); k++)
                            {
                                //Console.WriteLine(k + "я ship.ShipLocattion() = " + Convert.ToChar(ship.ShipLocattion()[k, 0] + 'A') + Convert.ToInt32(ship.ShipLocattion()[k, 1] + 1));
                                if ((ship.ShipLocattion()[k, 0] == ShL[i, 0] && ship.ShipLocattion()[k, 1] == ShL[i, 1]) || (shipNeighborhood[j, 0] == ShL[i, 0] && shipNeighborhood[j, 1] == ShL[i, 1]))
                                {
                                    throw new ShipAddingException();
                                }
                            }
                        }
                    }
                }
            }


            


                ShipType shipType = ship.ShipType;
                //Проверяем, не нарушено ли условие количества кораблей данного типа
                switch (shipType)
                {
                    case ShipType.AirCraftCarrie:
                        if (SummOfThisTypeShip(ship, f) == 1)
                        {
                            throw new ShipAddingException("Кораблей типа " + shipType + " максимально допуcтимое количество!");
                        }
                        break;
                    case ShipType.Destroyer:
                        if (SummOfThisTypeShip(ship, f) == 2)
                        {
                            throw new ShipAddingException("Кораблей типа " + shipType + " максимально допуcтимое количество!");
                        }
                        break;
                    case ShipType.Fregate:
                        if (SummOfThisTypeShip(ship, f) == 3)
                        {
                            throw new ShipAddingException("Кораблей типа " + shipType + " максимально допуcтимое количество!");
                        }
                        break;
                    case ShipType.Corvete:
                        if (SummOfThisTypeShip(ship, f) == 4)
                        {
                            throw new ShipAddingException("Кораблей типа " + shipType + " максимально допуcтимое количество!");
                        }
                        break;
                    default:
                        break;
                }

                if (ship.ShipLocattion().Length / ship.ShipLocattion().Rank > 4 || ship.ShipLocattion().Length / ship.ShipLocattion().Rank < 0)
                {
                    throw new ShipAddingException("Ошибка размера корабля!");
                }


                for (int i = 0; i < (ship.ShipLocattion().Length / ship.ShipLocattion().Rank); i++)
                {
                    f.Field[ship.ShipLocattion()[i, 1], ship.ShipLocattion()[i, 0]]._CellShipp = true;
                    
                }
                f.AllShipLocations.Add(ship.ShipLocattion());
                return field;
        }

        public int SummOfThisTypeShip(Ship ship, BattleField f)
        {
            int summ=0;
            for(int i=0; i<f.AllShipLocations.Capacity; i++){
                
            }
            foreach (int[,] k in f.AllShipLocations)
            {
                if (k.Length / k.Rank == ship.ShipLocattion().Length / ship.ShipLocattion().Rank)
                {
                    summ++;
                }
            }
            return summ;
        }

        public void Shot(string shotCoordinates, BattleField f)
        {
            int X = shotCoordinates[0] - 'A';

            int Y = Convert.ToInt32(shotCoordinates.Substring(1, shotCoordinates.Length - 1));
            f.Field[Y - 1, X]._Shoted = true;



            //Проверяем, убит ли корабль после выстрела.
            if (f.Field[Y - 1, X]._CellShipp == true)
            {

                foreach (int[,] ShL in f.AllShipLocations)
                {
                    //Console.WriteLine("adsd");
                    //Console.WriteLine(ShL[0, 1]);
                    int numberOfShips = ShL.Length / ShL.Rank; //Количество кораблей на поле
                    for (int i = 0; i < numberOfShips; i++)
                    {
                        int XShip = ShL[i, 0]; //i-я Х-координата корабля
                        int YShip = ShL[i, 1]; //i-я У-координата корабля
                        if (XShip == X && YShip == Y - 1)
                        {

                            int k = 0;
                            for (int j = 0; j < numberOfShips; j++)
                            {
                                //Считаем сколько палуб корабля ранено.
                                if (f.Field[ShL[j, 1], ShL[j, 0]]._CellShipp == true && f.Field[ShL[j, 1], ShL[j, 0]]._Shoted == true)
                                {


                                    k++;
                                }
                            }
                            //Если все палубы убиты - ставим точки вокруг корабля.

                            if (k == numberOfShips)
                            {
                                Utils a = new Utils();
                                int Y1ShipCoordinate = ShL[0, 1];
                                int X1ShipCoordinate = ShL[0, 0];
                                int Y2ShipCoordinate = ShL[numberOfShips - 1, 1];
                                int X2ShipCoordinate = ShL[numberOfShips - 1, 0];
                                int[,] array = a.GetNeighborhood(X1ShipCoordinate, Y1ShipCoordinate, X2ShipCoordinate, Y2ShipCoordinate);
                                
                                int numberOfCells = array.Length / array.Rank; // количество точек вокруг корабля
                                for (int j = 0; j < numberOfCells; j++)
                                {

                                    int YOfCell = array[j, 0]; //Y-кооординатая j-й клетки, соседней с кораблем 
                                    int XOfCell = array[j, 1]; //X-кооординатая j-й клетки, соседней с кораблем
                                    f.Field[XOfCell, YOfCell]._Shoted = true;
                                }
                            }
                        }

                    }
                }


            }
            Console.Clear();
            //f.Output();
            Console.BackgroundColor = ConsoleColor.Black;
        }

        public void ShipAddingAutomaticaly(BattleField f)
        {
            int i = 0;
            do
            {
            StartPoint:
                Random rnd = new Random();
                char startPointX = Convert.ToChar(rnd.Next(65, 74));
                int startPointY = rnd.Next(1, 10);
                int shipSize = rnd.Next(1, 5);
                int shipDirection = rnd.Next(1, 3); //1 - горизонтальный, 2 - вертикальный
                try
                {
                    if (shipDirection == 1)
                    {
                        if (startPointX + shipSize - 1 > 'J')
                        {
                            Ship ship = new Ship(startPointX, startPointY, Convert.ToChar(startPointX - shipSize + 1), startPointY);
                            f.addShip(ship, f);
                            i++;
                        }
                        else
                        {
                            Ship ship = new Ship(startPointX, startPointY, Convert.ToChar(startPointX + shipSize - 1), startPointY);
                            f.addShip(ship, f);
                            i++;
                        }
                    }
                    else
                    {
                        if (startPointY + shipSize - 1 > 10)
                        {
                            Ship ship = new Ship(startPointX, startPointY, startPointX, startPointY - shipSize + 1);
                            f.addShip(ship, f);
                            i++;
                        }
                        else
                        {
                            Ship ship = new Ship(startPointX, startPointY, startPointX, startPointY + shipSize - 1);
                            f.addShip(ship, f);
                            i++;
                        }
                    }
                }
                catch (ShipAddingException)
                {
                    goto StartPoint;
                }
            }
            while (i < 10);
            


        }
    }
}
